import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Elf class whose entire point is to make toys. If issues arise Appropriate
 * action is taken
 */
public class Elf extends Thread {
	// Name of the Elf
	public final String name;
	// Ensure all elves start at the same time
	private final CountDownLatch startSignal;
	
	// Maintains elves when they have a problem and allows them
	// to be sent back to work when Santa helps then
	private Lock lock;
	private Condition havingAProblem;

	/**
	 * Creates a new elf
	 * 
	 * @param name - name of the elf
	 */
	public Elf(String name, CountDownLatch latch) {
		this.name = name;
		startSignal = latch;
		lock = new ReentrantLock();
		havingAProblem = lock.newCondition();
	}

	/**
	 * Returns the name of the elf, used for printing out information
	 */
	public String toString() {
		return name;
	}

	/**
	 * The elf begins working on making toys
	 */
	@Override
	public void run() {
		try {
			startSignal.await();
		} catch (InterruptedException e) {

		}

		while (true) {
			lock.lock();
			try {

				Thread.sleep(Properties.randomNumber(Properties.ELF_MIN_WORKTIME,
						Properties.ELF_MAX_WORKTIME));

				System.out.println(name + " has a problem.");
				ElfQueue.getElfQueue().add(this);

				try {

					havingAProblem.await();

				} catch (InterruptedException ie) {
					ie.printStackTrace();
				}

			} catch (InterruptedException e) {
				e.printStackTrace();
			} finally {
				lock.unlock();
			}
		}

	}

	/**
	 * Accessor for the elves current state
	 * @return the condition associated with the elf
	 */
	public Condition getCondition() {
		return havingAProblem;
	}

	/**
	 * Accessor for the elves lock object
	 * @return the lock object for this elf
	 */
	public Lock getLock() {
		return lock;
	}

}